package com.sandu.facedetecter.facefilter;

import android.content.Context;
import android.graphics.PointF;
import android.opengl.GLES30;
import android.text.TextUtils;

import com.sandu.facedetecter.facepoint.EGLFace;
import com.sandu.facedetecter.facepoint.FacePointEngine;
import com.sandu.facedetecter.util.OpenGLUtils;

import java.nio.FloatBuffer;


public class FacePointsFilter extends BaseFilter {
    private static final String VERTEX_SHADER = "" +
            "attribute vec4 aPosition;\n" +
            "void main() {\n" +
            "    gl_Position = aPosition;\n" +
            "    gl_PointSize = 8.0;\n" +
            "}";

    private static final String FRAGMENT_SHADER = "" +
            "precision mediump float;\n" +
            "uniform vec4 color;\n" +
            "void main() {\n" +
            "    gl_FragColor = color;\n" +
            "}";

    private final float[] color = {1.0f, 0.0f, 0.0f, 1.0f};

    private int mColorHandle;
    private int mPointCount = 131;//114;
    private float[] mPoints;
    //连线的点
    private float[] mLinePoints;
    private int mLinePintCount = 22;
    private float[] mTriangePoints;
    private float[] mLeftEyesPoints;
    private float[] mRightEyesPoints;
    private float[] mMouthPoints;
    private float[] mHeadPoints;

    private float[] mComLinePoints;

    private FloatBuffer mPointVertexBuffer;
    private FloatBuffer mTriangeVertexBuffer;
    private FloatBuffer mLeftEyeVertexBuffer;
    private FloatBuffer mRightEyeVertexBuffer;
    private FloatBuffer mMouthVertexBuffer;
    private FloatBuffer mHeadVertexBuffer;
    private FloatBuffer mComLineVertexBuffer;

    public FacePointsFilter(Context context) {
        this(context, VERTEX_SHADER, FRAGMENT_SHADER);
    }

    public FacePointsFilter(Context context, String vertexShader, String fragmentShader) {
        super(context, vertexShader, fragmentShader);
        mPoints = new float[mPointCount * 2];
        mLinePoints = new float[mLinePintCount * 2];
        mTriangePoints = new float[6];
        mLeftEyesPoints = new float[8];
        mRightEyesPoints = new float[8];
        mMouthPoints = new float[8];
        mHeadPoints = new float[14];
        mComLinePoints = new float[100];


        //连线
//        mPoints = new float[mPointCount * 6];
        mPointVertexBuffer = OpenGLUtils.createFloatBuffer(mPoints);
        mTriangeVertexBuffer = OpenGLUtils.createFloatBuffer(mTriangePoints);
        mLeftEyeVertexBuffer = OpenGLUtils.createFloatBuffer(mLeftEyesPoints);
        mRightEyeVertexBuffer = OpenGLUtils.createFloatBuffer(mRightEyesPoints);
        mMouthVertexBuffer = OpenGLUtils.createFloatBuffer(mMouthPoints);
        mHeadVertexBuffer = OpenGLUtils.createFloatBuffer(mHeadPoints);
        mComLineVertexBuffer = OpenGLUtils.createFloatBuffer(mComLinePoints);
    }

    @Override
    public void initProgramHandle() {
        if (!TextUtils.isEmpty(mVertexShader) && !TextUtils.isEmpty(mFragmentShader)) {
            mProgramHandle = OpenGLUtils.createProgram(mVertexShader, mFragmentShader);
            mPositionHandle = GLES30.glGetAttribLocation(mProgramHandle, "aPosition");
            mColorHandle = GLES30.glGetUniformLocation(mProgramHandle, "color");
            mIsInitialized = true;
        } else {
            mPositionHandle = OpenGLUtils.GL_NOT_INIT;

            mColorHandle = OpenGLUtils.GL_NOT_INIT;
            mIsInitialized = false;
        }
        mTextureCoordinateHandle = OpenGLUtils.GL_NOT_INIT;
        mInputTextureHandle = OpenGLUtils.GL_NOT_TEXTURE;
    }

    @Override
    public void onInputSizeChanged(int width, int height) {
        super.onInputSizeChanged(width, height);
    }

    @Override
    public boolean drawFrame(int textureId, FloatBuffer vertexBuffer, FloatBuffer textureBuffer) {
        if (!mIsInitialized || !mFilterEnable) {
            return false;
        }
        GLES30.glViewport(0, 0, mDisplayWidth, mDisplayHeight);
        GLES30.glUseProgram(mProgramHandle);
        runPendingOnDrawTasks();
        GLES30.glEnableVertexAttribArray(mPositionHandle);
        GLES30.glUniform4fv(mColorHandle, 1, color, 0);
        onDrawFrameBegin();
        synchronized (this) {
            if (FacePointEngine.getInstance().getFaceSize() > 0) {
                EGLFace eglFace = FacePointEngine.getInstance().getOneFace(0);

                if (eglFace.vertexPoints != null) {
                    for (int i = 0; i < eglFace.vertexPoints.length-2; i++) {
                        mPoints[2 * i] = eglFace.vertexPoints[i].x;
                        mPoints[2 * i + 1] = eglFace.vertexPoints[i].y;
//
//                        mPoints[6 * i + 2] = eglFace.vertexPoints[i + 1].x;
//                        mPoints[6 * i + 3] = eglFace.vertexPoints[i + 1].y;


//                        mPoints[6 * i + 4] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2;
//                        mPoints[6 * i + 5] = (eglFace.vertexPoints[132].y) / 2 ;

//连线
//
//                        if (i <= 5) {
//                            mPoints[6 * i + 4] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2;
//                            mPoints[6 * i + 5] = eglFace.vertexPoints[132].y > 0 ? (eglFace.vertexPoints[132].y) * 2 : (eglFace.vertexPoints[132].y) / 2;
//                        } else if (i > 5 && i <= 10) {
//                            mPoints[6 * i + 4] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2 - 0.2f;
//                            mPoints[6 * i + 5] = (eglFace.vertexPoints[132].y) > 0 ? (eglFace.vertexPoints[132].y) * 1.5f : (eglFace.vertexPoints[132].y) / 2;
//                        } else if (i > 10 && i <= 25) {
//                            mPoints[6 * i + 4] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2;
//                            mPoints[6 * i + 5] = (eglFace.vertexPoints[132].y) > 0 ? (eglFace.vertexPoints[132].y) : (eglFace.vertexPoints[132].y) / 2;
//                            ;
//                        } else if (i > 25 && i <= 30) {
//                            mPoints[6 * i + 4] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2 + 0.2f;
//                            mPoints[6 * i + 5] = (eglFace.vertexPoints[132].y) > 0 ? (eglFace.vertexPoints[132].y) * 1.5f : (+eglFace.vertexPoints[132].y) / 1.5f;
//                        } else if (i > 30 && i <= 35) {
//                            mPoints[6 * i + 4] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2;
//                            mPoints[6 * i + 5] = (eglFace.vertexPoints[132].y) > 0 ? (eglFace.vertexPoints[132].y) * 2 : (eglFace.vertexPoints[132].y) / 2;
//                        } else {
//                            mPoints[6 * i + 4] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2;
//                            mPoints[6 * i + 5] = (eglFace.vertexPoints[132].y) / 2;
//                        }


                    }
                    //连线
//                    mPoints[(mPointCount - 28) * 2 + 0] = mPoints[0];
//                    mPoints[(mPointCount - 28) * 2 + 1] = mPoints[1];
//                    //添加标记点的连线
//                    //上部标记点
//                    mPoints[(mPointCount - 28) * 2 + 2] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2;
//                    mPoints[(mPointCount - 28) * 2 + 3] = eglFace.vertexPoints[132].y > 0 ? (eglFace.vertexPoints[132].y) * 2 : (eglFace.vertexPoints[132].y) / 2;
//                    //左部标记点
//                    mPoints[(mPointCount - 28) * 2 + 4] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2 - 0.2f;
//                    mPoints[(mPointCount - 28) * 2 + 5] = (eglFace.vertexPoints[132].y) > 0 ? (eglFace.vertexPoints[132].y) * 1.5f : (eglFace.vertexPoints[132].y) / 2;
//                    //下部标记点
//                    mPoints[(mPointCount - 28) * 2 + 6] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2;
//                    mPoints[(mPointCount - 28) * 2 + 7] = ((eglFace.vertexPoints[132].y) > 0) ? (eglFace.vertexPoints[132].y) : ((eglFace.vertexPoints[132].y) / 2);
//                    //右部标记点
//                    mPoints[(mPointCount - 28) * 2 + 8] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2 + 0.2f;
//                    mPoints[(mPointCount - 28) * 2 + 9] = (eglFace.vertexPoints[132].y) > 0 ? (eglFace.vertexPoints[132].y) * 1.5f : (+eglFace.vertexPoints[132].y) / 1.5f;
//                    //上部标记点
//                    mPoints[(mPointCount - 28) * 2 + 10] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2;
//                    mPoints[(mPointCount - 28) * 2 + 11] = eglFace.vertexPoints[132].y > 0 ? (eglFace.vertexPoints[132].y) * 2 : (eglFace.vertexPoints[132].y) / 2;
                    mPointVertexBuffer.clear();
//
//                    //下部标记点
//                    mPoints[(mPointCount - 28) * 2 + 12] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2;
//                    mPoints[(mPointCount - 28) * 2 + 13] = ((eglFace.vertexPoints[132].y) > 0) ? (eglFace.vertexPoints[132].y) : ((eglFace.vertexPoints[132].y) / 2);
//
//                    //左部标记点
//                    mPoints[(mPointCount - 28) * 2 + 14] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2 - 0.2f;
//                    mPoints[(mPointCount - 28) * 2 + 15] = (eglFace.vertexPoints[132].y) > 0 ? (eglFace.vertexPoints[132].y) * 1.5f : (eglFace.vertexPoints[132].y) / 2;
//
//                    //右部标记点
//                    mPoints[(mPointCount - 28) * 2 + 16] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2 + 0.2f;
//                    mPoints[(mPointCount - 28) * 2 + 17] = (eglFace.vertexPoints[132].y) > 0 ? (eglFace.vertexPoints[132].y) * 1.5f : (+eglFace.vertexPoints[132].y) / 1.5f;
//
//                    //上部标记点
//                    mPoints[(mPointCount - 28) * 2 + 18] = (eglFace.vertexPoints[131].x + eglFace.vertexPoints[132].x) / 2;
//                    mPoints[(mPointCount - 28) * 2 + 19] = eglFace.vertexPoints[132].y > 0 ? (eglFace.vertexPoints[132].y) * 2 : (eglFace.vertexPoints[132].y) / 2;

                    mLinePoints[0] = mPoints[6];
                    mLinePoints[1] = mPoints[7];

                    mLinePoints[2] = mPoints[14];
                    mLinePoints[3] = mPoints[15];

                    mLinePoints[4] = mPoints[24];
                    mLinePoints[5] = mPoints[25];
                    //chip
                    mLinePoints[6] = mPoints[38];
                    mLinePoints[7] = mPoints[39];

                    mLinePoints[8] = mPoints[50];
                    mLinePoints[9] = mPoints[51];

                    mLinePoints[10] = mPoints[60];
                    mLinePoints[11] = mPoints[61];

                    mLinePoints[12] = mPoints[68];
                    mLinePoints[13] = mPoints[69];

                    mLinePoints[0] = mPoints[6];
                    mLinePoints[1] = mPoints[7];

                    //left corner
                    mLinePoints[26] = mPoints[184];
                    mLinePoints[27] = mPoints[185];

                    mLinePoints[2] = mPoints[14];
                    mLinePoints[3] = mPoints[15];

                    //left corner
                    mLinePoints[26] = mPoints[184];
                    mLinePoints[27] = mPoints[185];
                    //top
                    mLinePoints[24] = mPoints[178];
                    mLinePoints[25] = mPoints[179];
                    //right corner
                    mLinePoints[22] = mPoints[170];
                    mLinePoints[23] = mPoints[171];
                    //bottom
                    mLinePoints[28] = mPoints[192];
                    mLinePoints[29] = mPoints[193];
                    //left corner
                    mLinePoints[26] = mPoints[184];
                    mLinePoints[27] = mPoints[185];
                    //top
                    mLinePoints[24] = mPoints[178];
                    mLinePoints[25] = mPoints[179];
                    //right corner
                    mLinePoints[22] = mPoints[170];
                    mLinePoints[23] = mPoints[171];


                    //right eye
                    //right corner
                    mLinePoints[14] = mPoints[72];
                    mLinePoints[15] = mPoints[73];
                    //top
                    mLinePoints[16] = mPoints[80];
                    mLinePoints[17] = mPoints[81];
                    //left corner
                    mLinePoints[18] = mPoints[88];
                    mLinePoints[19] = mPoints[89];
                    //bottom
                    mLinePoints[20] = mPoints[98];
                    mLinePoints[21] = mPoints[99];
                    //left eye
                    //right corner
                    mLinePoints[22] = mPoints[170];
                    mLinePoints[23] = mPoints[171];
                    //top
                    mLinePoints[24] = mPoints[178];
                    mLinePoints[25] = mPoints[179];
                    //left corner
                    mLinePoints[26] = mPoints[184];
                    mLinePoints[27] = mPoints[185];
                    //bottom
                    mLinePoints[28] = mPoints[192];
                    mLinePoints[29] = mPoints[193];
                    //鼻子
                    //top
                    mLinePoints[30] = mPoints[168];
                    mLinePoints[31] = mPoints[169];
                    //right
                    mLinePoints[32] = mPoints[164];
                    mLinePoints[33] = mPoints[165];
                    //left
                    mLinePoints[34] = mPoints[160];
                    mLinePoints[35] = mPoints[161];
                    //mouth
                    //left corner
                    mLinePoints[36] = mPoints[260];
                    mLinePoints[37] = mPoints[261];
                    //top lip
                    mLinePoints[38] = mPoints[252];
                    mLinePoints[39] = mPoints[253];
                    //bottom lip
                    mLinePoints[40] = mPoints[132];
                    mLinePoints[41] = mPoints[133];
                    //right corner
                    mLinePoints[42] = mPoints[140];
                    mLinePoints[43] = mPoints[141];

                    //鼻子
                    //top
                    mTriangePoints[0] = mPoints[168];
                    mTriangePoints[1] = mPoints[169];
                    //right
                    mTriangePoints[2] = mPoints[164];
                    mTriangePoints[3] = mPoints[165];
                    //left
                    mTriangePoints[4] = mPoints[160];
                    mTriangePoints[5] = mPoints[161];
                    //left eye
                    //right corner
                    mLeftEyesPoints[0] = mPoints[170];
                    mLeftEyesPoints[1] = mPoints[171];
                    //top
                    mLeftEyesPoints[2] = mPoints[178];
                    mLeftEyesPoints[3] = mPoints[179];
                    //left corner
                    mLeftEyesPoints[4] = mPoints[184];
                    mLeftEyesPoints[5] = mPoints[185];
                    //bottom
                    mLeftEyesPoints[6] = mPoints[192];
                    mLeftEyesPoints[7] = mPoints[193];

                    //right eye
                    //right corner
                    mRightEyesPoints[0] = mPoints[72];
                    mRightEyesPoints[1] = mPoints[73];
                    //top
                    mRightEyesPoints[2] = mPoints[80];
                    mRightEyesPoints[3] = mPoints[81];
                    //left corner
                    mRightEyesPoints[4] = mPoints[88];
                    mRightEyesPoints[5] = mPoints[89];
                    //bottom
                    mRightEyesPoints[6] = mPoints[98];
                    mRightEyesPoints[7] = mPoints[99];
                    //嘴巴
                    //mouth
                    //left corner
                    mMouthPoints[0] = mPoints[260];
                    mMouthPoints[1] = mPoints[261];
                    //top lip
                    mMouthPoints[2] = mPoints[250];
                    mMouthPoints[3] = mPoints[251];
                    //right corner
                    mMouthPoints[4] = mPoints[240];
                    mMouthPoints[5] = mPoints[241];
                    //bottom lip
                    mMouthPoints[6] = mPoints[132];
                    mMouthPoints[7] = mPoints[133];
                    //head
                    mHeadPoints[0] = mPoints[6];
                    mHeadPoints[1] = mPoints[7];

                    mHeadPoints[2] = mPoints[14];
                    mHeadPoints[3] = mPoints[15];

                    mHeadPoints[4] = mPoints[24];
                    mHeadPoints[5] = mPoints[25];
                    //chip
                    mHeadPoints[6] = mPoints[38];
                    mHeadPoints[7] = mPoints[39];

                    mHeadPoints[8] = mPoints[50];
                    mHeadPoints[9] = mPoints[51];

                    mHeadPoints[10] = mPoints[60];
                    mHeadPoints[11] = mPoints[61];

                    mHeadPoints[12] = mPoints[68];
                    mHeadPoints[13] = mPoints[69];

                    //com Lines

                    mComLinePoints[0] = mPoints[6];
                    mComLinePoints[1] = mPoints[7];
                    mComLinePoints[2] = mPoints[184];
                    mComLinePoints[3] = mPoints[185];
                    mComLinePoints[4] = mPoints[184];
                    mComLinePoints[5] = mPoints[185];
                    mComLinePoints[6] = mPoints[14];
                    mComLinePoints[7] = mPoints[15];

                    mComLinePoints[8] = mPoints[68];
                    mComLinePoints[9] = mPoints[69];
                    mComLinePoints[10] = mPoints[72];
                    mComLinePoints[11] = mPoints[73];

                    mComLinePoints[12] = mPoints[72];
                    mComLinePoints[13] = mPoints[73];
                    mComLinePoints[14] = mPoints[60];
                    mComLinePoints[15] = mPoints[61];
                    //鼻子 眼连接
                    mComLinePoints[16] = mPoints[170];
                    mComLinePoints[17] = mPoints[171];
                    mComLinePoints[18] = mPoints[88];
                    mComLinePoints[19] = mPoints[89];
                    mComLinePoints[20] = mPoints[88];
                    mComLinePoints[21] = mPoints[89];
                    mComLinePoints[22] = mPoints[168];
                    mComLinePoints[23] = mPoints[169];
                    mComLinePoints[24] = mPoints[168];
                    mComLinePoints[25] = mPoints[169];
                    mComLinePoints[26] = mPoints[170];
                    mComLinePoints[27] = mPoints[171];
                    //
                    mComLinePoints[28] = mPoints[14];
                    mComLinePoints[29] = mPoints[15];
                    mComLinePoints[30] = mPoints[164];
                    mComLinePoints[31] = mPoints[165];
                    mComLinePoints[32] = mPoints[160];
                    mComLinePoints[33] = mPoints[161];

                    mComLinePoints[34] = mPoints[60];
                    mComLinePoints[35] = mPoints[61];
                    //连嘴巴
                    mComLinePoints[36] = mPoints[164];
                    mComLinePoints[37] = mPoints[165];
                    mComLinePoints[38] = mPoints[260];
                    mComLinePoints[39] = mPoints[261];
                    mComLinePoints[40] = mPoints[260];
                    mComLinePoints[41] = mPoints[261];
                    mComLinePoints[42] = mPoints[24];
                    mComLinePoints[43] = mPoints[25];

                    mComLinePoints[44] = mPoints[160];
                    mComLinePoints[45] = mPoints[161];
                    mComLinePoints[46] = mPoints[240];
                    mComLinePoints[47] = mPoints[241];
                    mComLinePoints[48] = mPoints[240];
                    mComLinePoints[49] = mPoints[241];
                    mComLinePoints[50] = mPoints[50];
                    mComLinePoints[51] = mPoints[51];


                    mPointVertexBuffer.put(mPoints, 0, mPoints.length);
                    mPointVertexBuffer.position(0);

                    mTriangeVertexBuffer.put(mTriangePoints, 0, mTriangePoints.length);
                    mTriangeVertexBuffer.position(0);

                    mLeftEyeVertexBuffer.put(mLeftEyesPoints, 0, mLeftEyesPoints.length);
                    mLeftEyeVertexBuffer.position(0);

                    mRightEyeVertexBuffer.put(mRightEyesPoints, 0, mRightEyesPoints.length);
                    mRightEyeVertexBuffer.position(0);

                    mMouthVertexBuffer.put(mMouthPoints, 0, mMouthPoints.length);
                    mMouthVertexBuffer.position(0);

                    mHeadVertexBuffer.put(mHeadPoints, 0, mHeadPoints.length);
                    mHeadVertexBuffer.position(0);

                    mComLineVertexBuffer.put(mComLinePoints, 0, mComLinePoints.length);
                    mComLineVertexBuffer.position(0);


                    GLES30.glLineWidth(5);
                    GLES30.glVertexAttribPointer(mPositionHandle, 2,
                            GLES30.GL_FLOAT, false, 8, mPointVertexBuffer);


                    GLES30.glDrawArrays(GLES30.GL_POINTS, 0, mPointCount);
                    //画鼻子
                    GLES30.glVertexAttribPointer(mPositionHandle, 2,
                            GLES30.GL_FLOAT, false, 8, mTriangeVertexBuffer);
                    GLES30.glDrawArrays(GLES30.GL_LINE_LOOP, 0, 3);
                    //画左眼睛
                    GLES30.glVertexAttribPointer(mPositionHandle, 2,
                            GLES30.GL_FLOAT, false, 8, mLeftEyeVertexBuffer);
                    GLES30.glDrawArrays(GLES30.GL_LINE_LOOP, 0, 4);
                    //画右眼
                    GLES30.glVertexAttribPointer(mPositionHandle, 2,
                            GLES30.GL_FLOAT, false, 8, mRightEyeVertexBuffer);
                    GLES30.glDrawArrays(GLES30.GL_LINE_LOOP, 0, 4);
                    //画嘴巴
                    GLES30.glVertexAttribPointer(mPositionHandle, 2,
                            GLES30.GL_FLOAT, false, 8, mMouthVertexBuffer);
                    GLES30.glDrawArrays(GLES30.GL_LINE_LOOP, 0, 4);
                    //轮廓
                    GLES30.glVertexAttribPointer(mPositionHandle, 2,
                            GLES30.GL_FLOAT, false, 8, mHeadVertexBuffer);
                    GLES30.glDrawArrays(GLES30.GL_LINE_LOOP, 0, 7);

                    //连线
                    GLES30.glVertexAttribPointer(mPositionHandle, 2,
                            GLES30.GL_FLOAT, false, 8, mComLineVertexBuffer);
                    GLES30.glDrawArrays(GLES30.GL_LINES, 0, 26);


//                    GLES30.glDrawArrays(GLES30.GL_LINE_LOOP, 0, mPointCount - 28);
//                    GLES30.glDrawArrays(GLES30.GL_LINE_LOOP, 0, mPointCount - 18);
                }
            }
        }
        onDrawFrameAfter();
        GLES30.glDisableVertexAttribArray(mPositionHandle);
        return true;
    }

    @Override
    public int drawFrameBuffer(int textureId, FloatBuffer vertexBuffer, FloatBuffer textureBuffer) {
        if (textureId == OpenGLUtils.GL_NOT_TEXTURE || mFrameBuffers == null
                || !mIsInitialized || !mFilterEnable) {
            return textureId;
        }
        drawFrame(textureId, vertexBuffer, textureBuffer);
        return textureId;
    }

    @Override
    public void initFrameBuffer(int width, int height) {
        // do nothing
    }

    @Override
    public void destroyFrameBuffer() {
        // do nothing
    }
}
